//
// 光照强度传感器
//

package modules

import (
	"encoding/binary"
	"time"
	"adai.design/homemaster/log"
	"errors"
)

type LightSensor struct {
	lux 		uint32
	infrared	uint16
	result 		chan []byte

	lastLux uint32
	lastInfrared uint16
}

func (l *LightSensor) handle(data []byte) error {
	l.lux = binary.BigEndian.Uint32(data[:])
	l.infrared = binary.BigEndian.Uint16(data[4:])


	var abs uint32
	if l.lux > l.lastLux {
		abs = l.lux - l.lastLux
	} else {
		abs = l.lastLux - l.lux
	}

	//if l.lastLux != 0 {
	//	log.Debug("lux(%d) infrared(%d) last(%v) diff(%0.2f)", l.lux, l.infrared, l.lastLux, float32(abs) / float32(l.lastLux))
	//}

	if l.lux > 100 && float32(abs) / float32(l.lastLux) > 0.08 {
		lightService.Light.UpdateValue(int(l.lux))
		lightService.Infrared.UpdateValue(l.infrared)
		l.lastLux = l.lux
	} else if l.lux < 100 &&  abs > 10 {
		lightService.Light.UpdateValue(int(l.lux))
		lightService.Infrared.UpdateValue(l.infrared)
		l.lastLux = l.lux
	}

	SetClockAutoBrightness(l.lux)
	return nil
}

func (l *LightSensor) measure() {
	for {
		select {
		case <-time.After(time.Second * 5):
			msg := &MasterMessage{
				pkgType: MasterLightSensor,
				data:    []byte{0x01},
			}
			err := masterSendMessage(msg)
			if err != nil {
				log.Notice("light sensor measure err: %s", err)
			}

		case data, ok := <-l.result:
			if !ok {
				return
			}
			l.handle(data)

		}
	}
}

var light = LightSensor{}

func lightObserverMessage(m *MasterMessage) error {
	if len(m.data) != 6 {
		return errors.New("light measure result format err")
	}

	if light.result == nil {
		return errors.New("light measure result channel has been closed")
	}

	light.result <- m.data
	return nil
}

func StartLightMeasure() {
	addObserver(MasterLightSensor, lightObserverMessage)
	light.result = make(chan []byte, 1)
	go light.measure()
}

func StopLightMeasure() {
	if light.result != nil {
		close(light.result)
		light.result = nil
	}
	removeObserver(MasterLightSensor)
}

